package com.huan.vertxle.verticle;

import com.huan.vertxle.enums.EventBusBusinessEnum;
import com.huan.vertxle.initialization.StartParamsInit;
import com.huan.vertxle.model.ConfigParams;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.Slf4JLoggerFactory;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.ServerWebSocket;

import java.util.HashMap;
import java.util.Map;

/**
 * @author huan
 */
public class WebsocketVerticle extends AbstractVerticle {

  private final InternalLogger logger = Slf4JLoggerFactory.getInstance(this.getClass());

  /**
   * 保存每一个连接到服务器的通道
   */
  private final Map<String, ServerWebSocket> connectionMap = new HashMap<>(16);

  /**
   * 如果您的 Verticle 执行简单的同步启动，则覆盖此方法并将您的启动代码放在此处。
   *
   * @throws Exception
   */
  @Override
  public void start() throws Exception {
    Vertx vertx = Vertx.currentContext().owner();
    EventBus eventBus = vertx.eventBus();
    HttpServer server = vertx.createHttpServer();
    server.webSocketHandler(websocket -> {
      // 建立连接触发 不在map中则添加
      String id = websocket.binaryHandlerID();
      logger.info("websocket建立链接:{}", id);
      if (!connectionMap.containsKey(id)) {
        connectionMap.put(id, websocket);
      }
      // 消息推送过来触发
      websocket.frameHandler(handler -> {
        String data = handler.textData();
        for (Map.Entry<String, ServerWebSocket> socketEntry : connectionMap.entrySet()) {
          socketEntry.getValue().writeTextMessage(data);
        }
        logger.info("websocket传递消息:{},{},{}", id, Thread.currentThread(), data);
        eventBus.<Long>request(EventBusBusinessEnum.BUSINESS_SCAN.name(), data)
          .onSuccess(msg -> {
            Long lastId = msg.body();
            logger.info("最新ID为:{}", lastId);
          })
          .onFailure(event -> logger.error(event.getMessage()));
      });
      // 链接关闭触发
      websocket.closeHandler(handler -> {
        connectionMap.remove(id);
        logger.info("断开连接:{}", id);
      });
      // 发生异常
      websocket.exceptionHandler(handler -> logger.error("websocket链接异常:{}", handler.getMessage()));
    });
    ConfigParams.WebsocketDTO websocket = StartParamsInit.init.getWebsocket();
    server.listen(websocket.getPort());
    logger.info("WebSocket启动端口:{}", websocket.getPort());
  }
}
